package com.teamwings.config.filter;

import com.teamwings.util.HttpHelper;
import com.teamwings.util.XssHelper;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 请求代理类
 */
public class ParameterRequestWrapper extends HttpServletRequestWrapper {

	private Map<String, String[]> params;
	private byte[] body;

	public ParameterRequestWrapper(HttpServletRequest request) throws IOException {
		super(request);
		String method = request.getMethod();
		// delete一般为get形式
		if ("GET".equalsIgnoreCase(method) || "DELETE".equalsIgnoreCase(method)) {
			// xxx/xxx/xxx/param形式，暂未解决获取param参数
			params = HttpHelper.getParamMap(request);
		} else if ("POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) {
			String bodyString = HttpHelper.getBodyString(request);
			body = bodyString.getBytes(StandardCharsets.UTF_8);
			if (StringUtils.isNotEmpty(bodyString)) {
				params = HttpHelper.getBodyMap(bodyString);
			}
		}
	}

	@Override
	public BufferedReader getReader() throws IOException {
		return new BufferedReader(new InputStreamReader(getInputStream()));
	}

	@Override
	public ServletInputStream getInputStream() throws IOException {
		ByteArrayInputStream bis = new ByteArrayInputStream(body);
		return new MyServletInputStream(bis);
	}

	@Override
	public String getParameter(String name) {
		String[] values = params.get(name);
		if (values == null || values.length == 0) {
			return null;
		}
		return values[0];
	}

	@Override
	public Enumeration<String> getParameterNames() {
		Vector<String> v = new Vector<>();
		Set<Map.Entry<String, String[]>> entrySet = params.entrySet();
		for (Map.Entry<String, String[]> entry : entrySet) {
			v.add(entry.getKey());
		}
		return v.elements();
	}

	@Override
	public String[] getParameterValues(String name) {
		return params.get(name);
	}

	public final boolean checkParameter() {
		if (params == null) {
			return false;
		}
		Map<String, String[]> submitParams = new HashMap<>(params);
		Set<String> submitNames = submitParams.keySet();
		for (String submitName : submitNames) {
			Object submitValues = submitParams.get(submitName);
			if ((submitValues != null)) {
				for (String submitValue : (String[]) submitValues) {
					if (XssHelper.checkXssAndSql(submitValue)) {
						return true;
					}
				}
			}
		}
		return false;
	}

	class MyServletInputStream extends ServletInputStream {

		private ByteArrayInputStream bis;

		public MyServletInputStream(ByteArrayInputStream bis) {
			this.bis = bis;
		}

		@Override
		public boolean isFinished() {
			return true;
		}

		@Override
		public boolean isReady() {
			return true;
		}

		@Override
		public void setReadListener(ReadListener readListener) {

		}

		@Override
		public int read() throws IOException {
			return bis.read();
		}
	}
}
